#ifndef _LINUX_PT_DEV_H
#define _LINUX_PT_DEV_H

#include <linux/types.h>
#include "drv_pcie.h"
#include "drv_pcie_irq.h"
#include "drv_cdev.h"
#include "drv_pcie_dma.h"

#define PT_MAX_CHANNEL                  32

/* IOCTL 命令定义 */
#define IOCTL_PT_MAGIC                  'P'                                         /* 标识设备驱动 */
#define IOCTL_PT_SET_MODE               _IOW(IOCTL_PT_MAGIC, 1, u8)                 /* 配置 PT 模式 */
#define IOCTL_PT_SET_OSR                _IOW(IOCTL_PT_MAGIC, 2, u8)                 /* 配置 PT 过采样 */
#define IOCTL_PT_SET_SAMP_RATE          _IOW(IOCTL_PT_MAGIC, 3, u32)                /* 配置 PT 采样频率 */
#define IOCTL_PT_SET_IRQ_RATE           _IOW(IOCTL_PT_MAGIC, 4, u16)                /* 配置 PT 中断频率 */
#define IOCTL_PT_SET_SLID_WIN           _IOW(IOCTL_PT_MAGIC, 5, u16)                /* 配置 PT 滑动平均窗口 */
#define IOCTL_PT_SET_RANGE              _IOW(IOCTL_PT_MAGIC, 6, u8)                 /* 配置 PT 量程 */
#define IOCTL_PT_GET_VAL                _IOR(IOCTL_PT_MAGIC, 7, s32)                /* 获取 PT 数值 */
// #define IOCTL_PT_WPTT_TIM_IRQ           _IOR(IOCTL_PT_MAGIC, 8, struct ai_buf_t)    /* 等待 PT 定时中断 */
#define IOCTL_PT_START                  _IO(IOCTL_PT_MAGIC,  9)                     /* 开始 PT 采集 */
#define IOCTL_PT_STOP                   _IO(IOCTL_PT_MAGIC,  10)                    /* 停止 PT 采集 */

#define IOCTL_PT_CHK_MODE               _IOR(IOCTL_PT_MAGIC, 51, u8)                /* 核查 PT 模式 */
#define IOCTL_PT_CHK_OSR                _IOR(IOCTL_PT_MAGIC, 52, u8)                /* 核查 PT 过采样 */
#define IOCTL_PT_CHK_SAMP_RATE          _IOR(IOCTL_PT_MAGIC, 53, u32)               /* 核查 PT 采样频率 */
#define IOCTL_PT_CHK_IRQ_RATE           _IOR(IOCTL_PT_MAGIC, 54, u16)               /* 核查 PT 中断频率 */
#define IOCTL_PT_CHK_SLID_WIN           _IOR(IOCTL_PT_MAGIC, 55, u16)               /* 核查 PT 滑动平均窗口 */
#define IOCTL_PT_CHK_RANGE              _IOR(IOCTL_PT_MAGIC, 56, u8)                /* 核查 PT 量程 */
#define IOCTL_PT_CHK_CMD                _IOR(IOCTL_PT_MAGIC, 57, u16)               /* 核查 PT 指令 */

#define IOCTL_PT_GET_DRV_VERSION        _IOR(IOCTL_PT_MAGIC, 101, u32)              /* 获取驱动版本号 */
#define IOCTL_PT_GET_FPGA_VERSION       _IOR(IOCTL_PT_MAGIC, 102, u32)              /* 获取 FPGA 版本号 */

enum pt_cmd {
    PT_CMD_START        = 0x1111,       /* 开始 PT 采集指令 */
    PT_CMD_STOP         = 0x2222,       /* 停止 PT 采集指令 */
    PT_CMD_CONFIG       = 0x3333,       /* 配置 PT 参数指令 */
};

enum pt_range {
    PT_RANGE_10V0       = 0x00,         /* ±10V */
    PT_RANGE_2V5        = 0x01,         /* ±2.5V */
    PT_RANGE_5V         = 0X02,         /* ±5V */
    PT_RANGE_10V        = 0x03,         /* ±10V */
};

enum pt_mode {
    PT_MOD_SMP          = 0,            /* 连续采集, 滑窗滤波, 不发中断 */
    PT_MOD_SMP_TIM      = 1,            /* 连续采集, 定时（抽样滑窗数据）触发PCIe中断 */
    PT_MOD_RAW_DMA      = 2,            /* 连续采集, 原始数据, 发DMA中断 */
    PT_MOD_RAW          = 3,            /* 连续采集, 原始数据, 不发中断 */
};

enum pt_osr {
    PT_OSR_0            = 0,            /* 过采样值 0 */
    PT_OSR_2            = 2,            /* 过采样值 2 */
    PT_OSR_4            = 4,            /* 过采样值 4 */
    PT_OSR_8            = 8,            /* 过采样值 8 */
    PT_OSR_16           = 16,           /* 过采样值 16 */
    PT_OSR_32           = 32,           /* 过采样值 32 */
    PT_OSR_64           = 64,           /* 过采样值 64 */
    PT_OSR_128          = 128,          /* 过采样值 128 */
};

enum pt_type {
    PT_TYPE_AC          = 0,            /* PT 属于 AC 模块 */
    PT_TYPE_PT100       = 1,            /* PT 属于 PT100 模块 */
    PT_TYPE_AI          = 2,            /* PT 属于 AI 模块 */
};

/* PT 设备 */
struct pt_dev_t {
    void *parent;                       /* 父设备指针 */
    struct device *dev;                 /* 设备描述符 */
    struct mutex lock;                  /* 互斥锁 */
    char name[32];                      /* 设备名称 */
    u8 index;                           /* 索引号 */

    u8 range;                           /* 量程 */
    u8 chk_range;                       /* 量程核查值 */
};

/* PT 控制器 */
struct pt_ctrl_t {
    struct device *dev;                                                 /* 设备描述符 */
    struct mutex lock;                                                  /* 互斥锁 */
    char name[32];                                                      /* 设备名称 */
    u8 num;                                                             /* 设备数量 */

    struct pcie_dev_t *pcie_dev;                                        /* PCIe 设备指针 */
    u32 (*read_reg)(struct pcie_dev_t *pcie_dev, u32 reg);              /* 读寄存器 */
    void (*write_reg)(struct pcie_dev_t *pcie_dev, u32 reg, u32 val);   /* 写寄存器 */
    struct cdev_ctrl_t cdev_ctrl;                                       /* 字符设备 */
    struct pt_dev_t *pt;                                                /* pt */
    u8 type;                                                            /* PT 类型 */
    u8 id[PT_MAX_CHANNEL];                                              /* PT 通道顺序 */
    s32 val[PT_MAX_CHANNEL];                                            /* PT 通道数据 */
    u8 mode;                                                            /* PT 模式 */
    u8 chk_mode;                                                        /* PT 模式核查值 */
    u8 osr;                                                             /* PT 过采样值 */
    u8 chk_osr;                                                         /* PT 过采样核查值 */
    u16 interval;                                                       /* PT 采样间隔, us */
    u16 chk_interval;                                                   /* PT 采样间隔核查值, us */
    u32 samp_rate;                                                      /* PT 采样率, 1~100000Hz */
    u16 chk_samp_rate;                                                  /* PT 采样率核查值 */
    u16 samp_tim;                                                       /* PT 抽样定时间隔 */
    u16 chk_samp_tim;                                                   /* PT 抽样定时间隔核查值 */
    u16 slid_win;                                                       /* PT 滑动平均窗口 */
    u16 chk_slid_win;                                                   /* PT 滑动平均窗口核查值 */
    u16 cmd;                                                            /* PT 指令 */
    u16 chk_cmd;                                                        /* PT 指令核查值*/

    bool is_tim_irq;                                                    /* 定时中断 */
    wait_queue_head_t tim_wq;                                           /* 定时器 等待队列 */
    struct work_struct dma_irq_work;                                    /*  工作队列(中断下半部) */

    u32 drv_ver;                                                        /* 驱动版本号 */
    u32 fpga_ver;                                                       /* FPGA 版本号 */
};

/* 初始化 PT 控制器 */
int init_pt_ctrl(struct pcie_dev_t *pcie_dev, struct cdev_dev_t *cdev_dev, 
                 struct pt_ctrl_t *pctrl, struct pt_dev_t *pt, 
                 const char *ctrl_name, u8 dev_num);
/* 注销 PT 控制器 */
void exit_pt_ctrl(struct pt_ctrl_t *ctrl, u8 dev_num);

#endif /* _LINUX_PT_DEV_H */
